// 首先在文件顶部添加全局测试统计变量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lexer.h"
#include "token.h"
#include "parser.h"
#include "semantic_analyzer.h"
#include "plan_generator.h"
#include "ast.h"
#include "plan.h"
#include "catalog.h"

// 测试统计变量
int total_tests = 0;
int lexer_success = 0;
int parser_success = 0;
int semantic_success = 0;
int plan_success = 0;

// 打印Token信息，按照要求的格式：[种别码,词素值,行号,列号]
void print_token(Token* token) {
    printf("[%s, %s, %d, %d]\n", 
           token_type_to_string(token->type), 
           token->lexeme, 
           token->line, 
           token->column);
}

// 打印AST节点信息
void print_ast(ASTNode* node, int indent) {
    if (!node) return;
    
    // 打印缩进
    for (int i = 0; i < indent; i++) {
        printf("  ");
    }
    
    // 根据节点类型打印不同信息
    switch (node->type) {
        case NODE_CREATE_TABLE:
            {
                CreateTableStmt* stmt = (CreateTableStmt*)node->extra_data;
                printf("CREATE TABLE: %s\n", stmt->table_name);
                
                // 打印列定义
                for (int i = 0; i < stmt->column_count; i++) {
                    for (int j = 0; j < indent + 1; j++) {
                        printf("  ");
                    }
                    printf("COLUMN: %s, ", stmt->columns[i].name);
                    
                    switch (stmt->columns[i].type) {
                        case TYPE_INT:
                            printf("INT");
                            break;
                        case TYPE_VARCHAR:
                            printf("VARCHAR(%d)", stmt->columns[i].length);
                            break;
                        case TYPE_FLOAT:
                            printf("FLOAT");
                            break;
                        case TYPE_DOUBLE:
                            printf("DOUBLE");
                            break;
                        default:
                            printf("UNKNOWN");
                            break;
                    }
                    printf("\n");
                }
            }
            break;
        case NODE_INSERT:
            {
                InsertStmt* stmt = (InsertStmt*)node->extra_data;
                printf("INSERT INTO: %s\n", stmt->table_name);
                
                // 打印列名（如果有）
                if (stmt->column_count > 0) {
                    for (int j = 0; j < indent + 1; j++) {
                        printf("  ");
                    }
                    printf("COLUMNS:");
                    for (int i = 0; i < stmt->column_count; i++) {
                        printf(" %s", stmt->columns[i]);
                    }
                    printf("\n");
                }
            }
            break;
        case NODE_SELECT:
            printf("SELECT\n");
            break;
        case NODE_DELETE:
            printf("DELETE\n");
            break;
        case NODE_DROP_TABLE:
            printf("DROP TABLE\n");
            break;
        case NODE_ALTER_TABLE:
            printf("ALTER TABLE\n");
            break;
        case NODE_UPDATE:
            printf("UPDATE\n");
            break;
        default:
            printf("UNKNOWN NODE TYPE\n");
            break;
    }
    
    // 递归打印子节点
    if (node->left) {
        print_ast(node->left, indent + 1);
    }
    if (node->right) {
        print_ast(node->right, indent + 1);
    }
}

// 测试完整的SQL编译器功能
void test_full_compiler(const char* input) {
    total_tests++;
    printf("\n=== SQL编译器完整测试 ===\n");
    printf("测试用例 %d: %s\n\n", total_tests, input);
    
    int current_lexer_success = 0;
    int current_parser_success = 0;
    int current_semantic_success = 0;
    int current_plan_success = 0;
    
    // 步骤1: 词法分析
    printf("【词法分析结果】\n");
    Lexer* lexer = create_lexer(input);
    if (!lexer) {
        printf("错误: 创建词法分析器失败\n");
        return;
    }
    
    // 保存Token序列用于语法分析
    Token** tokens = NULL;
    int token_count = 0;
    Token* token;
    TokenType type;
    
    do {
        token = get_next_token(lexer);
        if (!token) {
            printf("错误: 无法获取Token\n");
            break;
        }
        
        // 扩展Token数组
        tokens = realloc(tokens, (token_count + 1) * sizeof(Token*));
        tokens[token_count] = token;
        token_count++;
        
        type = token->type;
        print_token(token);
        
        // 错误处理
        if (type == ERROR) {
            printf("词法分析错误: 非法字符，位置: 行 %d, 列 %d\n", token->line, token->column);
            // 释放资源
            for (int i = 0; i < token_count; i++) {
                free_token(tokens[i]);
            }
            free(tokens);
            free_lexer(lexer);
            return;
        }
    } while (type != EOF_TOKEN);
    
    // 词法分析成功
    current_lexer_success = 1;
    lexer_success++;
    
    // 释放词法分析器
    free_lexer(lexer);
    
    // 重新创建词法分析器用于语法分析
    lexer = create_lexer(input);
    if (!lexer) {
        printf("错误: 重新创建词法分析器失败\n");
        // 释放资源
        for (int i = 0; i < token_count; i++) {
            free_token(tokens[i]);
        }
        free(tokens);
        return;
    }
    
    // 步骤2: 语法分析
    printf("\n【语法分析结果】\n");
    Parser* parser = create_parser(lexer);
    if (!parser) {
        printf("错误: 创建语法分析器失败\n");
        // 释放资源
        free_lexer(lexer);
        for (int i = 0; i < token_count; i++) {
            free_token(tokens[i]);
        }
        free(tokens);
        return;
    }
    
    ASTNode* ast = parse_statement(parser);
    if (ast) {
        print_ast(ast, 0);
        current_parser_success = 1;
        parser_success++;
    } else {
        printf("语法分析失败\n");
        // 释放资源
        free_parser(parser);
        free_lexer(lexer);
        for (int i = 0; i < token_count; i++) {
            free_token(tokens[i]);
        }
        free(tokens);
        return;
    }
    
    // 步骤3: 语义分析
    printf("\n【语义分析结果】\n");
    Catalog* catalog = create_catalog();
    if (!catalog) {
        printf("错误: 创建模式目录失败\n");
        // 释放资源
        free_ast_node(ast);
        free_parser(parser);
        free_lexer(lexer);
        for (int i = 0; i < token_count; i++) {
            free_token(tokens[i]);
        }
        free(tokens);
        return;
    }
    
    SemanticResult sem_result = analyze_semantics(ast, catalog);
    if (sem_result.success) {
        printf("语义分析成功\n");
        current_semantic_success = 1;
        semantic_success++;
    } else {
        printf("语义分析错误: %s, 行 %d, 列 %d\n", 
               sem_result.error_message, sem_result.error_line, sem_result.error_column);
        free(sem_result.error_message);
        // 释放资源
        free_ast_node(ast);
        free_parser(parser);
        free_lexer(lexer);
        free_catalog(catalog);
        for (int i = 0; i < token_count; i++) {
            free_token(tokens[i]);
        }
        free(tokens);
        return;
    }
    
    // 步骤4: 执行计划生成
    printf("\n【执行计划生成结果】\n");
    PlanNode* plan = generate_plan(ast, catalog);
    if (plan) {
        print_plan(plan,0);
        free_plan(plan);
        current_plan_success = 1;
        plan_success++;
    } else {
        printf("执行计划生成失败\n");
    }
    
    // 释放所有资源
    free_ast_node(ast);
    free_parser(parser);
    free_lexer(lexer);
    free_catalog(catalog);
    
    for (int i = 0; i < token_count; i++) {
        free_token(tokens[i]);
    }
    free(tokens);
    
    printf("\n=== 测试完成 ===\n\n");
}

// 在main函数末尾添加测试总结
int main() {
    system("chcp 65001");
    
    printf("=== SQL编译器完整测试 ===\n\n");
    
    // 测试用例1: CREATE TABLE语句
    test_full_compiler("CREATE TABLE customers (id INT, name VARCHAR(50), age INT);");
    
    // 测试用例2: INSERT语句
    test_full_compiler("INSERT INTO customers VALUES (1, 'Alice', 30);");
    
    // 测试用例3: SELECT语句
    test_full_compiler("SELECT id, name FROM customers;");
    
    // 测试用例4: DELETE语句
    test_full_compiler("DELETE FROM customers WHERE id = 1;");
    
    // 测试用例5: ALTER TABLE语句
    test_full_compiler("ALTER TABLE customers ADD COLUMN email VARCHAR(100);");
    
    // 测试用例6: UPDATE语句
    test_full_compiler("UPDATE customers SET age = 31 WHERE name = 'Alice';");
    
    // 测试用例7: DROP TABLE语句
    test_full_compiler("DROP TABLE customers;");
    
    // 测试用例8: 错误处理 - 语法错误
    test_full_compiler("CREATE TABLE without_columns;");
    
    // 测试用例9: 错误处理 - 语义错误
    test_full_compiler("SELECT non_existent_column FROM customers;");
    
    // 测试用例10: 复杂查询语句
    test_full_compiler("SELECT id, name, age FROM customers WHERE age > 25 AND name LIKE 'A%';");
    
    printf("\n=== 所有编译器测试用例执行完毕 ===\n");
    
    // 添加测试总结
    printf("\n=== 测试总结 ===\n");
    printf("总测试用例数: %d\n", total_tests);
    printf("词法分析成功率: %d/%d (%.1f%%)\n", lexer_success, total_tests, (float)lexer_success/total_tests*100);
    printf("语法分析成功率: %d/%d (%.1f%%)\n", parser_success, lexer_success, (float)parser_success/lexer_success*100);
    printf("语义分析成功率: %d/%d (%.1f%%)\n", semantic_success, parser_success, (float)semantic_success/parser_success*100);
    printf("执行计划生成成功率: %d/%d (%.1f%%)\n", plan_success, semantic_success, (float)plan_success/semantic_success*100);
    printf("\n总体完成度: %.1f%%\n", (float)(lexer_success + parser_success + semantic_success + plan_success)/(total_tests*4)*100);
    
    system("pause");
    
    return 0;
}